/*
 * Copyright 2023, Haiku, Inc.
 * Distributed under the terms of the MIT License.
 */


#include "ArchitectureLoongArch64.h"

#include <new>

#include <String.h>

#include <AutoDeleter.h>

#include "CfaContext.h"
#include "CpuStateLoongArch64.h"
#include "DisassembledCode.h"
#include "FunctionDebugInfo.h"
#include "InstructionInfo.h"
#include "NoOpStackFrameDebugInfo.h"
#include "RegisterMap.h"
#include "StackFrame.h"
#include "Statement.h"
#include "TeamMemory.h"
#include "ValueLocation.h"

// LoongArch64的DWARF寄存器映射
// 参考：https://github.com/loongson/la-abi-specs/blob/main/la64-abi-specs.adoc
static const int32 kFromDwarfRegisters[] = {
	LOONGARCH64_REGISTER_R0,
	LOONGARCH64_REGISTER_RA,
	LOONGARCH64_REGISTER_TP,
	LOONGARCH64_REGISTER_SP,
	LOONGARCH64_REGISTER_A0,
	LOONGARCH64_REGISTER_A1,
	LOONGARCH64_REGISTER_A2,
	LOONGARCH64_REGISTER_A3,
	LOONGARCH64_REGISTER_A4,
	LOONGARCH64_REGISTER_A5,
	LOONGARCH64_REGISTER_A6,
	LOONGARCH64_REGISTER_A7,
	LOONGARCH64_REGISTER_T0,
	LOONGARCH64_REGISTER_T1,
	LOONGARCH64_REGISTER_T2,
	LOONGARCH64_REGISTER_T3,
	LOONGARCH64_REGISTER_T4,
	LOONGARCH64_REGISTER_T5,
	LOONGARCH64_REGISTER_T6,
	LOONGARCH64_REGISTER_T7,
	LOONGARCH64_REGISTER_T8,
	LOONGARCH64_REGISTER_S0,
	LOONGARCH64_REGISTER_S1,
	LOONGARCH64_REGISTER_S2,
	LOONGARCH64_REGISTER_S3,
	LOONGARCH64_REGISTER_S4,
	LOONGARCH64_REGISTER_S5,
	LOONGARCH64_REGISTER_S6,
	LOONGARCH64_REGISTER_S7,
	LOONGARCH64_REGISTER_S8,
	LOONGARCH64_REGISTER_PC,
	LOONGARCH64_REGISTER_F0,
	LOONGARCH64_REGISTER_F1,
	LOONGARCH64_REGISTER_F2,
	LOONGARCH64_REGISTER_F3,
	LOONGARCH64_REGISTER_F4,
	LOONGARCH64_REGISTER_F5,
	LOONGARCH64_REGISTER_F6,
	LOONGARCH64_REGISTER_F7,
	LOONGARCH64_REGISTER_F8,
	LOONGARCH64_REGISTER_F9,
	LOONGARCH64_REGISTER_F10,
	LOONGARCH64_REGISTER_F11,
	LOONGARCH64_REGISTER_F12,
	LOONGARCH64_REGISTER_F13,
	LOONGARCH64_REGISTER_F14,
	LOONGARCH64_REGISTER_F15,
	LOONGARCH64_REGISTER_F16,
	LOONGARCH64_REGISTER_F17,
	LOONGARCH64_REGISTER_F18,
	LOONGARCH64_REGISTER_F19,
	LOONGARCH64_REGISTER_F20,
	LOONGARCH64_REGISTER_F21,
	LOONGARCH64_REGISTER_F22,
	LOONGARCH64_REGISTER_F23,
	LOONGARCH64_REGISTER_F24,
	LOONGARCH64_REGISTER_F25,
	LOONGARCH64_REGISTER_F26,
	LOONGARCH64_REGISTER_F27,
	LOONGARCH64_REGISTER_F28,
	LOONGARCH64_REGISTER_F29,
	LOONGARCH64_REGISTER_F30,
	LOONGARCH64_REGISTER_F31,
};

static const int32 kFromDwarfRegisterCount = sizeof(kFromDwarfRegisters) / sizeof(int32);
static const uint16 kFunctionPrologueSize = 4;


// #pragma mark - ToDwarfRegisterMap


struct ArchitectureLoongArch64::ToDwarfRegisterMap : RegisterMap {
	virtual ~ToDwarfRegisterMap()
	{
	}

	virtual int32 MapRegisterIndex(int32 index) const
	{
		if (index < 0 || index >= LOONGARCH64_REGISTER_COUNT)
			return -1;

		// 对于LoongArch64，DWARF寄存器索引与我们的寄存器索引相同
		return index;
	}
};


// #pragma mark - FromDwarfRegisterMap


struct ArchitectureLoongArch64::FromDwarfRegisterMap : RegisterMap {
	virtual ~FromDwarfRegisterMap()
	{
	}

	virtual int32 MapRegisterIndex(int32 index) const
	{
		if (index < 0 || index >= kFromDwarfRegisterCount)
			return -1;

		return kFromDwarfRegisters[index];
	}
};


// #pragma mark - ArchitectureLoongArch64


ArchitectureLoongArch64::ArchitectureLoongArch64(TeamMemory* teamMemory)
	:
	Architecture(teamMemory, 8, sizeof(loongarch64_debug_cpu_state), false),
	fFeatureFlags(LOONGARCH64_CPU_FEATURE_FLAG_NONE),
	fRegisters(),
	fAssemblyLanguage(NULL),
	fToDwarfRegisterMap(NULL),
	fFromDwarfRegisterMap(NULL)
{
}


ArchitectureLoongArch64::~ArchitectureLoongArch64()
{
	delete fAssemblyLanguage;
	delete fToDwarfRegisterMap;
	delete fFromDwarfRegisterMap;
}


status_t
ArchitectureLoongArch64::Init()
{
	// 初始化寄存器
	// 通用寄存器
	_AddIntegerRegister(LOONGARCH64_REGISTER_R0, "r0", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_RA, "ra", B_UINT64_TYPE,
		REGISTER_TYPE_RETURN_ADDRESS, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_TP, "tp", B_UINT64_TYPE,
		REGISTER_TYPE_SPECIAL_PURPOSE, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_SP, "sp", B_UINT64_TYPE,
		REGISTER_TYPE_STACK_POINTER, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_A0, "a0", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_A1, "a1", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_A2, "a2", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_A3, "a3", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_A4, "a4", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_A5, "a5", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_A6, "a6", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_A7, "a7", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_T0, "t0", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_T1, "t1", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_T2, "t2", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_T3, "t3", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_T4, "t4", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_T5, "t5", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_T6, "t6", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_T7, "t7", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_T8, "t8", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, false);
	_AddIntegerRegister(LOONGARCH64_REGISTER_S0, "s0", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_S1, "s1", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_S2, "s2", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_S3, "s3", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_S4, "s4", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_S5, "s5", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_S6, "s6", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_S7, "s7", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_S8, "s8", B_UINT64_TYPE,
		REGISTER_TYPE_GENERAL_PURPOSE, true);
	_AddIntegerRegister(LOONGARCH64_REGISTER_PC, "pc", B_UINT64_TYPE,
		REGISTER_TYPE_INSTRUCTION_POINTER, false);

	// 浮点寄存器
	_AddFPRegister(LOONGARCH64_REGISTER_F0, "f0");
	_AddFPRegister(LOONGARCH64_REGISTER_F1, "f1");
	_AddFPRegister(LOONGARCH64_REGISTER_F2, "f2");
	_AddFPRegister(LOONGARCH64_REGISTER_F3, "f3");
	_AddFPRegister(LOONGARCH64_REGISTER_F4, "f4");
	_AddFPRegister(LOONGARCH64_REGISTER_F5, "f5");
	_AddFPRegister(LOONGARCH64_REGISTER_F6, "f6");
	_AddFPRegister(LOONGARCH64_REGISTER_F7, "f7");
	_AddFPRegister(LOONGARCH64_REGISTER_F8, "f8");
	_AddFPRegister(LOONGARCH64_REGISTER_F9, "f9");
	_AddFPRegister(LOONGARCH64_REGISTER_F10, "f10");
	_AddFPRegister(LOONGARCH64_REGISTER_F11, "f11");
	_AddFPRegister(LOONGARCH64_REGISTER_F12, "f12");
	_AddFPRegister(LOONGARCH64_REGISTER_F13, "f13");
	_AddFPRegister(LOONGARCH64_REGISTER_F14, "f14");
	_AddFPRegister(LOONGARCH64_REGISTER_F15, "f15");
	_AddFPRegister(LOONGARCH64_REGISTER_F16, "f16");
	_AddFPRegister(LOONGARCH64_REGISTER_F17, "f17");
	_AddFPRegister(LOONGARCH64_REGISTER_F18, "f18");
	_AddFPRegister(LOONGARCH64_REGISTER_F19, "f19");
	_AddFPRegister(LOONGARCH64_REGISTER_F20, "f20");
	_AddFPRegister(LOONGARCH64_REGISTER_F21, "f21");
	_AddFPRegister(LOONGARCH64_REGISTER_F22, "f22");
	_AddFPRegister(LOONGARCH64_REGISTER_F23, "f23");
	_AddFPRegister(LOONGARCH64_REGISTER_F24, "f24");
	_AddFPRegister(LOONGARCH64_REGISTER_F25, "f25");
	_AddFPRegister(LOONGARCH64_REGISTER_F26, "f26");
	_AddFPRegister(LOONGARCH64_REGISTER_F27, "f27");
	_AddFPRegister(LOONGARCH64_REGISTER_F28, "f28");
	_AddFPRegister(LOONGARCH64_REGISTER_F29, "f29");
	_AddFPRegister(LOONGARCH64_REGISTER_F30, "f30");
	_AddFPRegister(LOONGARCH64_REGISTER_F31, "f31");

	// 创建DWARF寄存器映射
	fToDwarfRegisterMap = new(std::nothrow) ToDwarfRegisterMap;
	if (fToDwarfRegisterMap == NULL)
		return B_NO_MEMORY;

	fFromDwarfRegisterMap = new(std::nothrow) FromDwarfRegisterMap;
	if (fFromDwarfRegisterMap == NULL)
		return B_NO_MEMORY;

	return B_OK;
}


int32
ArchitectureLoongArch64::StackGrowthDirection() const
{
	return STACK_GROWTH_DIRECTION_NEGATIVE;
}


int32
ArchitectureLoongArch64::CountRegisters() const
{
	return fRegisters.Count();
}


const Register*
ArchitectureLoongArch64::Registers() const
{
	return fRegisters.Elements();
}


status_t
ArchitectureLoongArch64::InitRegisterRules(CfaContext& context) const
{
	// 调用基类实现
	status_t result = Architecture::InitRegisterRules(context);
	if (result != B_OK)
		return result;

	// 设置返回地址寄存器规则
	RegisterMap* toDwarf = NULL;
	result = GetDwarfRegisterMaps(&toDwarf, NULL);
	if (result != B_OK)
		return result;

	BReference<RegisterMap> toDwarfMapReference(toDwarf, true);
	int32 dwarfReg = toDwarf->MapRegisterIndex(LOONGARCH64_REGISTER_RA);
	if (dwarfReg >= 0)
		context.RegisterRule(dwarfReg)->SetToRegister(dwarfReg);

	return B_OK;
}


status_t
ArchitectureLoongArch64::GetDwarfRegisterMaps(RegisterMap** _toDwarf,
	RegisterMap** _fromDwarf) const
{
	if (_toDwarf != NULL) {
		*_toDwarf = fToDwarfRegisterMap;
		fToDwarfRegisterMap->AcquireReference();
	}

	if (_fromDwarf != NULL) {
		*_fromDwarf = fFromDwarfRegisterMap;
		fFromDwarfRegisterMap->AcquireReference();
	}

	return B_OK;
}


status_t
ArchitectureLoongArch64::GetCpuFeatures(uint32& flags)
{
	flags = fFeatureFlags;
	return B_OK;
}


status_t
ArchitectureLoongArch64::CreateCpuState(CpuState*& _state)
{
	_state = new(std::nothrow) CpuStateLoongArch64;
	if (_state == NULL)
		return B_NO_MEMORY;

	return B_OK;
}


status_t
ArchitectureLoongArch64::CreateCpuState(const void* cpuStateData, size_t size,
	CpuState*& _state)
{
	if (size != sizeof(loongarch64_debug_cpu_state))
		return B_BAD_VALUE;

	_state = new(std::nothrow) CpuStateLoongArch64(
		*(const loongarch64_debug_cpu_state*)cpuStateData);
	if (_state == NULL)
		return B_NO_MEMORY;

	return B_OK;
}


status_t
ArchitectureLoongArch64::CreateStackFrame(Image* image, FunctionDebugInfo* function,
	CpuState* cpuState, bool isTopFrame, StackFrame*& _frame,
	CpuState*& _previousCpuState)
{
	// 创建堆栈帧
	StackFrame* frame = new(std::nothrow) StackFrame(this, cpuState);
	if (frame == NULL)
		return B_NO_MEMORY;
	BReference<StackFrame> frameReference(frame, true);

	// 获取指令指针和栈指针
	target_addr_t instructionPointer = cpuState->InstructionPointer();
	target_addr_t framePointer = ((CpuStateLoongArch64*)cpuState)->IntRegisterValue(
		LOONGARCH64_REGISTER_S0);
	target_addr_t stackPointer = ((CpuStateLoongArch64*)cpuState)->IntRegisterValue(
		LOONGARCH64_REGISTER_SP);

	// 设置帧地址
	frame->SetFrameAddress(framePointer);

	// 如果是顶部帧，则返回地址就是指令指针
	if (isTopFrame) {
		frame->SetReturnAddress(instructionPointer);
		_previousCpuState = NULL;
		_frame = frame;
		frameReference.Detach();
		return B_OK;
	}

	// 对于非顶部帧，需要从栈上获取返回地址
	// LoongArch64的调用约定是将返回地址保存在RA寄存器中
	target_addr_t returnAddress = ((CpuStateLoongArch64*)cpuState)->IntRegisterValue(
		LOONGARCH64_REGISTER_RA);
	frame->SetReturnAddress(returnAddress);

	// 创建前一个CPU状态
	CpuStateLoongArch64* previousCpuState = new(std::nothrow) CpuStateLoongArch64;
	if (previousCpuState == NULL)
		return B_NO_MEMORY;
	BReference<CpuStateLoongArch64> previousCpuStateReference(previousCpuState, true);

	// 设置前一个CPU状态的指令指针为返回地址
	previousCpuState->SetIntRegister(LOONGARCH64_REGISTER_PC, returnAddress);

	// 设置前一个CPU状态的栈指针和帧指针
	// 在LoongArch64中，函数调用时会保存调用者的帧指针
	// 假设帧指针在栈上的偏移为0
	target_addr_t previousFramePointer = 0;
	if (framePointer != 0) {
		status_t error = fTeamMemory->ReadMemory(framePointer, &previousFramePointer,
			sizeof(target_addr_t));
		if (error != B_OK)
			previousFramePointer = 0;
	}

	previousCpuState->SetIntRegister(LOONGARCH64_REGISTER_S0, previousFramePointer);
	previousCpuState->SetIntRegister(LOONGARCH64_REGISTER_SP, framePointer + 16);

	_frame = frame;
	_previousCpuState = previousCpuState;

	frameReference.Detach();
	previousCpuStateReference.Detach();

	return B_OK;
}


void
ArchitectureLoongArch64::UpdateStackFrameCpuState(const StackFrame* frame,
	Image* previousImage, FunctionDebugInfo* previousFunction,
	CpuState* previousCpuState)
{
	// 如果前一个CPU状态的指令指针是当前帧的返回地址，则需要调整
	if (previousCpuState != NULL
		&& previousCpuState->InstructionPointer() == frame->ReturnAddress()) {
		// 调整指令指针，使其指向调用指令而不是返回地址
		previousCpuState->SetInstructionPointer(
			previousCpuState->InstructionPointer() - 4);
	}
}


status_t
ArchitectureLoongArch64::ReadValueFromMemory(target_addr_t address, uint32 valueType,
	BVariant& _value) const
{
	return ReadValueFromMemory(0, address, valueType, _value);
}


status_t
ArchitectureLoongArch64::ReadValueFromMemory(target_addr_t addressSpace,
	target_addr_t address, uint32 valueType, BVariant& _value) const
{
	// 根据值类型读取内存
	uint8 buffer[16];
	size_t size;

	switch (valueType) {
		case B_INT8_TYPE:
		case B_UINT8_TYPE:
			size = 1;
			break;
		case B_INT16_TYPE:
		case B_UINT16_TYPE:
			size = 2;
			break;
		case B_INT32_TYPE:
		case B_UINT32_TYPE:
			size = 4;
			break;
		case B_INT64_TYPE:
		case B_UINT64_TYPE:
			size = 8;
			break;
		case B_FLOAT_TYPE:
			size = 4;
			break;
		case B_DOUBLE_TYPE:
			size = 8;
			break;
		default:
			return B_BAD_VALUE;
	}

	status_t error = fTeamMemory->ReadMemory(address, buffer, size);
	if (error != B_OK)
		return error;

	// 转换为适当的类型
	switch (valueType) {
		case B_INT8_TYPE:
			_value.SetTo(*(int8*)buffer);
			break;
		case B_UINT8_TYPE:
			_value.SetTo(*(uint8*)buffer);
			break;
		case B_INT16_TYPE:
			_value.SetTo(*(int16*)buffer);
			break;
		case B_UINT16_TYPE:
			_value.SetTo(*(uint16*)buffer);
			break;
		case B_INT32_TYPE:
			_value.SetTo(*(int32*)buffer);
			break;
		case B_UINT32_TYPE:
			_value.SetTo(*(uint32*)buffer);
			break;
		case B_INT64_TYPE:
			_value.SetTo(*(int64*)buffer);
			break;
		case B_UINT64_TYPE:
			_value.SetTo(*(uint64*)buffer);
			break;
		case B_FLOAT_TYPE:
			_value.SetTo(*(float*)buffer);
			break;
		case B_DOUBLE_TYPE:
			_value.SetTo(*(double*)buffer);
			break;
		default:
			return B_BAD_VALUE;
	}

	return B_OK;
}


status_t
ArchitectureLoongArch64::DisassembleCode(FunctionDebugInfo* function,
	const void* buffer, size_t bufferSize, DisassembledCode*& _sourceCode)
{
	// 目前暂不实现反汇编功能
	// 在实际实现中，需要添加LoongArch64的反汇编器
	return B_NOT_SUPPORTED;
}


status_t
ArchitectureLoongArch64::GetStatement(FunctionDebugInfo* function,
	target_addr_t address, Statement*& _statement)
{
	// 目前暂不实现语句查找功能
	return B_NOT_SUPPORTED;
}


status_t
ArchitectureLoongArch64::GetInstructionInfo(target_addr_t address,
	InstructionInfo& _info, CpuState* state)
{
	// 初始化指令信息
	_info.SetTo(address);

	// 读取指令
	uint32 instruction;
	status_t error = fTeamMemory->ReadMemory(address, &instruction, 4);
	if (error != B_OK)
		return error;

	// 目前仅提供基本支持，不进行详细指令分析
	// 在实际实现中，需要根据LoongArch64指令集进行详细分析
	_info.SetType(INSTRUCTION_TYPE_OTHER);
	_info.SetSize(4);

	return B_OK;
}


status_t
ArchitectureLoongArch64::ResolvePICFunctionAddress(target_addr_t instructionAddress,
	CpuState* state, target_addr_t& _targetAddress)
{
	// 目前暂不实现PIC函数地址解析
	return B_NOT_SUPPORTED;
}


status_t
ArchitectureLoongArch64::GetWatchpointDebugCapabilities(int32& _maxRegisterCount,
	int32& _maxBytesPerRegister, uint8& _watchpointCapabilityFlags)
{
	// LoongArch64的硬件断点和监视点能力
	// 这些值需要根据实际硬件规格进行调整
	_maxRegisterCount = 4;
	_maxBytesPerRegister = 8;
	_watchpointCapabilityFlags = WATCHPOINT_CAPABILITY_FLAG_READ
		| WATCHPOINT_CAPABILITY_FLAG_WRITE
		| WATCHPOINT_CAPABILITY_FLAG_READ_WRITE;

	return B_OK;
}


status_t
ArchitectureLoongArch64::GetReturnAddressLocation(StackFrame* frame,
	target_size_t valueSize, ValueLocation*& _location)
{
	// 在LoongArch64中，返回地址通常保存在RA寄存器中
	_location = new(std::nothrow) ValueLocation();
	if (_location == NULL)
		return B_NO_MEMORY;

	_location->SetToRegister(LOONGARCH64_REGISTER_RA);
	return B_OK;
}


void
ArchitectureLoongArch64::_AddRegister(int32 index, const char* name,
	uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved)
{
	Register* reg = new(std::nothrow) Register(index, name, bitSize, valueType,
		type, calleePreserved);
	if (reg != NULL)
		fRegisters.Add(reg);
}


void
ArchitectureLoongArch64::_AddIntegerRegister(int32 index, const char* name,
	uint32 valueType, register_type type, bool calleePreserved)
{
	_AddRegister(index, name, 64, valueType, type, calleePreserved);
}


void
ArchitectureLoongArch64::_AddFPRegister(int32 index, const char* name)
{
	_AddRegister(index, name, 64, B_DOUBLE_TYPE, REGISTER_TYPE_EXTENDED, false);
}


void
ArchitectureLoongArch64::_AddSIMDRegister(int32 index, const char* name,
	uint32 byteSize)
{
	_AddRegister(index, name, byteSize * 8, B_UINT64_TYPE, REGISTER_TYPE_EXTENDED, false);
}


bool
ArchitectureLoongArch64::_HasFunctionPrologue(FunctionDebugInfo* function) const
{
	// 检查函数是否有序言
	// 在LoongArch64中，典型的函数序言包括保存帧指针和栈指针的指令
	return true;
}